package controllers

// srs
import (
	"encoding/json"
	//	"fmt"
	"gitee.com/lzqysoft/ims/libs/cache"
	"gitee.com/lzqysoft/ims/libs/encrypt"
	"gitee.com/lzqysoft/ims/libs/ffmpeg"
	"gitee.com/lzqysoft/ims/libs/pathtool"
	"gitee.com/lzqysoft/ims/libs/seaweed"
	//	"reflect"

	"io"
	"gitee.com/lzqysoft/ims/models"
	"os"
	"os/exec"
	"path/filepath"
	// "strconv"
	"time"

	"github.com/astaxie/beego"
)

type SrsController struct {
	beego.Controller
}

func (a *SrsController) Prepare() {
	a.EnableXSRF = false
}

func (c *SrsController) URLMapping() {
	c.Mapping("Onconnect", c.Onconnect)
	c.Mapping("Onclose", c.Onclose)
	c.Mapping("Onpublish", c.Onpublish)
	c.Mapping("Onunpublish", c.Onunpublish)
	c.Mapping("Onplay", c.Onplay)
	c.Mapping("Onstop", c.Onstop)
	c.Mapping("Ondvr", c.Ondvr)
	c.Mapping("Ontest", c.Ontest)
}

// @Title on_connect
// @Description 当客户端连接到指定的vhost和app时
// @Success 200 0
// @Failure 403 : -1
// @router /Onconnect [post]
func (c *SrsController) Onconnect() {
	req := c.Ctx.Input.RequestBody
	var dat map[string]interface{}
	c.Data["json"] = 0
	if err := json.Unmarshal(req, &dat); err == nil {
		beego.Notice("action 是 : ", dat["action"])
		beego.Notice("ip 是 : ", dat["ip"])
		beego.Notice("client_id 是 : ", dat["client_id"])
		beego.Notice("vhost 是 : ", dat["vhost"])
		beego.Notice("app 是 : ", dat["app"])
		beego.Notice("tcUrl 是 : ", dat["tcUrl"])
		beego.Notice("pageUrl 是 : ", dat["pageUrl"])
	} else {
		c.Data["json"] = -1
		beego.Error("非法数据！！：", err)
	}
	c.ServeJSON()
}

// @Title Onclose
// @Description 当客户端关闭连接，或者SRS主动关闭连接时
// @Success 200 0
// @Failure 403 : -1
// @router /Onclose [post]
func (c *SrsController) Onclose() {
	req := c.Ctx.Input.RequestBody
	var dat map[string]interface{}
	c.Data["json"] = 0
	if err := json.Unmarshal(req, &dat); err == nil {
	} else {
		c.Data["json"] = -1
		beego.Error("非法数据！！：", err)
	}
	beego.Debug("Onclose")
	c.ServeJSON()
}

// @Title on_publish
// @Description 当客户端发布流时，推流到服务器
// @Success 200 0
// @Failure 403 : -1
// @router /Onpublish [post]
func (c *SrsController) Onpublish() {
	req := c.Ctx.Input.RequestBody
	var dat map[string]interface{}
	c.Data["json"] = 0

	if err := json.Unmarshal(req, &dat); err == nil {
		stream := dat["stream"].(string)
		lv, err := models.GetLivechannelByStream(stream)
		if err != nil {
			beego.Error("此频道无权限或不存在", err)
			c.Data["json"] = -1
			c.ServeJSON()
			c.StopRun()
		}
		cmdName := "ffmpeg  -i " + dat["tcUrl"].(string) +
			"/" + dat["stream"].(string) +
			" -vf fps=1 -vcodec png -f image2 -ss 00:00:1 -an -y -vframes 3 -y " +
			"/data/root/live/" + lv.Id + ".png"
		cmd := exec.Command("sh", "-c", cmdName)
		//		stdout, _ := cmd.StdoutPipe()
		//	log.Notice("cmd  is :", cmd)
		cmd.Start()

		img := "/data/root/live/" + lv.Id + ".png"
		err = seaweed.UbdateFile(lv.Img, img)

		//		lv.Img = fid
		//		err = models.UpdateLivechannelById(lv)
		if err != nil {
			c.Data["json"] = -1
			beego.Error("非法数据！！：", err)
		} else {
			//			os.Remove(img)
		}

	} else {
		c.Data["json"] = -1
		beego.Error("非法数据！！：", err)
	}

	c.ServeJSON()
}

// @Title on_unpublish
// @Description 当客户端停止发布流时
// @Success 200 0
// @Failure 403 : -1
// @router /Onunpublish [post]
func (c *SrsController) Onunpublish() {
	req := c.Ctx.Input.RequestBody
	var dat map[string]interface{}
	c.Data["json"] = 0
	if err := json.Unmarshal(req, &dat); err != nil {
		beego.Error("非法数据！！：", err)
		c.ServeJSON()
		c.StopRun()
	}
	stream := dat["stream"].(string)
	lv, err := models.GetLivechannelByStream(stream)
	// 修改频道画面为停止画面
	err = seaweed.UbdateFile(lv.Img, "imgs/times.jpg")
	if err != nil {
		beego.Error("文件系统错误！！：", err)
		c.ServeJSON()
		c.StopRun()
	}
	//从cache获取此stream的合并列表文件
	var filelist string
	ckey := stream + "filelist"
	cache.GetCache(ckey, &filelist)
	//合并视频
	outfile, err := ffmpeg.FfmpegJoin(filelist)
	if err != nil {
		beego.Error("合并失败：", err)
		c.ServeJSON()
		c.StopRun()
	}
	// 获取合并后视频的时长/画面
	err, duration, dur, imgPath := ffmpeg.FfmpegActImag(outfile)
	if err != nil {
		beego.Error("ffmpeg错误：", err)
		c.ServeJSON()
		c.StopRun()
	}
	img, _, _ := seaweed.SetFile(imgPath)
	fid, size, err := seaweed.SetFile(outfile)
	if err != nil {
		beego.Error("文件系统错误！！：", err)
		c.ServeJSON()
		c.StopRun()
	}
	//写入数据库
	var v models.Video
	v.Id = encrypt.GetGuid()
	v.Organization = lv.Organization
	v.OrgName = lv.OrgName
	v.Title = lv.Title + time.Now().Format("2006-01-02 15:04:05")
	v.Creater = "admin"
	v.Ctime = time.Now()
	v.Length = duration
	v.Longtime = dur
	v.Updater = "admin"
	v.Utime = v.Ctime
	v.Scope = lv.Scope
	v.Dept = lv.Dept
	v.Status = 1
	v.Img = img
	v.Url = fid
	v.Size = size / 1024
	_, err = models.AddVideo(&v)
	if err != nil {
		beego.Error("视频录制错误：", err)
	}
	// 删除所有视频文件
	filedir, _ := filepath.Split(outfile)
	os.RemoveAll(filedir)
	// os.Remove(filename)
	beego.Debug("Onunpublish", filedir, outfile)
	c.ServeJSON()
}

// @Title on_play
// @Description 当客户端开始播放流时
// @Success 200 0
// @Failure 403 : -1
// @router /Onplay [post]
func (c *SrsController) Onplay() {
	req := c.Ctx.Input.RequestBody
	var dat map[string]interface{}
	c.Data["json"] = 0
	if err := json.Unmarshal(req, &dat); err == nil {
		beego.Debug("action 是 : ", dat["action"])
		beego.Debug("ip 是 : ", dat["ip"])
		beego.Debug("client_id 是 : ", dat["client_id"])
		beego.Debug("vhost 是 : ", dat["vhost"])
		beego.Debug("app 是 : ", dat["app"])
		beego.Debug("stream 是 : ", dat["stream"])
		beego.Debug("pageUrl 是 : ", dat["pageUrl"])
	} else {
		c.Data["json"] = -1
		beego.Error("非法数据！！：", err)
	}
	c.ServeJSON()
}

// @Title on_stop
// @Description 当客户端停止播放时。备注：停止播放可能不会关闭连接，还能再继续播放。
// @Success 200 0
// @Failure 403 : -1
// @router /Onstop [post]
func (c *SrsController) Onstop() {
	req := c.Ctx.Input.RequestBody
	var dat map[string]interface{}
	c.Data["json"] = 0
	if err := json.Unmarshal(req, &dat); err == nil {
		beego.Notice("action 是 : ", dat["action"])
		beego.Notice("ip 是 : ", dat["ip"])
		beego.Notice("client_id 是 : ", dat["client_id"])
		beego.Notice("vhost 是 : ", dat["vhost"])
		beego.Notice("app 是 : ", dat["app"])
		beego.Notice("stream 是 : ", dat["stream"])
	} else {
		c.Data["json"] = -1
		beego.Error("非法数据！！：", err)
	}
	c.ServeJSON()
}

// @Title on_test
// @Description 当客户端开始播放流时
// @Success 200 0
// @Failure 403 : -1
// @router /Ontest [get]
func (c *SrsController) Ontest() {
	req := c.Ctx.Input.RequestBody
	var dat map[string]interface{}
	c.Data["json"] = 0
	if err := json.Unmarshal(req, &dat); err == nil {
		beego.Debug("action 是 : ", dat["action"])
		beego.Debug("ip 是 : ", dat["ip"])
		beego.Debug("client_id 是 : ", dat["client_id"])
		beego.Debug("vhost 是 : ", dat["vhost"])
		beego.Debug("app 是 : ", dat["app"])
		beego.Debug("stream 是 : ", dat["stream"])
		beego.Debug("pageUrl 是 : ", dat["pageUrl"])
	} else {
		c.Data["json"] = -1
		beego.Error("非法数据！！：", err)
	}
	c.ServeJSON()
}

// @Title Ondvr录制完成后提交文件
// @Description 录制完毕后写入数据库录制记录
// @Success 200 0
// @Failure 403 : -1
// @router /Ondvr [post]
func (c *SrsController) Ondvr() {
	req := c.Ctx.Input.RequestBody
	var dat map[string]interface{}
	c.Data["json"] = 0
	// 获取请求数据
	if err := json.Unmarshal(req, &dat); err != nil {
		beego.Error(err)
		c.ServeJSON()
		c.StopRun()
	}
	filename := dat["file"].(string)
	stream := dat["stream"].(string)
	livechannel, err := models.GetLivechannelByStream(stream)
	// 获取频道数据
	if livechannel == nil || err != nil {
		os.Remove(filename)
		beego.Error("此频道无权限或不存在", err)
		c.ServeJSON()
		c.StopRun()
	}
	c.Data["json"] = 0
	//判断是否需要录像
	if livechannel.Type == 0 {
		os.Remove(filename)
		c.ServeJSON()
		c.StopRun()
	}
	//判断存储空间占用是否已经超出95%
	percent := models.GetUsedDiskPercent(*livechannel.Organization)
	if percent > 95 {
		os.Remove(filename)
		c.ServeJSON()
		c.StopRun()
	}

	//				dir, file := filepath.Split(filename)
	//				_, dir2 := filepath.Split(filepath.Dir(dir))
	//				newdir := "/data/root/live/" + strconv.Itoa(int(livechannel.Id)) + "/" + dir2
	//				libs.CheckPath(newdir)
	//				newfile := newdir + "/" + file
	//				cmdName := "mv -f " + filename + "  " + newdir + "/" + file

	//				beego.Debug("filename is :", filename)
	//				beego.Debug("filefilefile is :", file)
	//				beego.Debug("newfilenewfile is :", newfile)
	//				beego.Debug("cmdNamecmdName is :", cmdName)
	//				cmd := exec.Command("sh", "-c", cmdName)
	//				cmd.Run()

	// 添加到合并文件列表
	var f *os.File
	filedir, file := filepath.Split(filename)
	filelist := filedir + "filelist.txt"
	if pathtool.CheckFileIsExist(filelist) { //如果文件存在
		f, err = os.OpenFile(filelist, os.O_APPEND|os.O_WRONLY, os.ModeAppend) //打开文件
	} else {
		f, err = os.Create(filelist) //创建文件
	}
	if err != nil {
		beego.Error(err)
	}
	times := 3600 * 24
	ckey := stream + "filelist"
	// 将此stream的合并文件列表添加到cache
	err = cache.SetCache(ckey, filelist, times)
	if err != nil {
		beego.Error(err)
	}
	//将此视频文件写入合并列表文件
	filewrite := "file " + "'" + file + "'\n"
	_, err = io.WriteString(f, filewrite) //写入文件(字符串)
	defer f.Close()
	if err != nil {
		beego.Error(err)
	}
	c.ServeJSON()
}

//// @Title Ondvr录制完成后提交文件
//// @Description 录制完毕后写入数据库录制记录
//// @Success 200 0
//// @Failure 403 : -1
//// @router /Ondvr [post]
//func (c *SrsController) Ondvr() {
//	req := c.Ctx.Input.RequestBody
//	var dat map[string]interface{}
//	if err := json.Unmarshal(req, &dat); err == nil {
//		beego.Notice("ip 是 %s,文件为：%s", dat["ip"], dat["file"])
//		filename := dat["file"].(string)
//		stream := dat["stream"].(string)

//		livechannel, err := models.GetLivechannelByStream(stream)
//		if livechannel == nil || err != nil {
//			beego.Error("此频道无权限或不存在", err)
//			err = os.Remove(filename)
//			c.Data["json"] = -1
//		} else {
//			c.Data["json"] = 0
//			_, duration, dur, img := libs.FfmpegActImag(filename)
//			var v models.Video
//			v.Organization = livechannel.Organization
//			v.OrgName = livechannel.OrgName
//			v.Title = livechannel.Title + time.Now().Format("2006-01-02 15:04:05")
//			v.Creater = "admin"
//			v.Ctime = time.Now()
//			v.Length = duration
//			v.Longtime = dur
//			beego.Debug("视频时长", duration)
//			v.Updater = "admin"
//			v.Utime = v.Ctime
//			v.Scope = livechannel.Scope
//			v.Dept = livechannel.Dept
//			v.Status = 1
//			v.Img = libs.SplitPath(img)
//			v.Url = libs.SplitPath(filename)
//			size, _ := libs.FileSize(filename)
//			v.Size = size / 1024
//			id, err := models.AddVideo(&v)
//			if err != nil {
//				beego.Error("视频录制错误：", err)
//			}
//			beego.Debug("视频录制成功：编号为%d", id)

//		}
//	} else {
//		c.Data["json"] = -1
//		beego.Error("非法数据！！：", err)

//	}
//	c.ServeJSON()
//}
